#include "stdafx.h"
#include "qtabcontainer.h"



using namespace micro::gui;

const   int  SPACE_TAB		= 25;
const   int  SPACE_ACTIVE	= 1; //linia de la tabul selectat
const   int  SPACE_LINE		= 3; //linia de la tab-bar 26-
const   int  SPACE_CORNER	= 5;





#define QTAB		_T("TAB")




QTabContainer::QTabContainer( void )
{

    m_currentTab = 0;
    m_style = TS_MAXTAB;
    m_bkColor = ::GetSysColor( COLOR_BTNFACE );

}



QTabContainer::~QTabContainer( void )
{
    m_tabList.RemoveAll();
    m_theme.CloseThemeData();
}

void QTabContainer::SetStyle( UINT style )
{
    m_style = style;

    RecalcLayout();//neceasr pt a aseza clientul
    Invalidate();
}

void QTabContainer::SetBkColor( QCOLOR c )
{
    m_bkColor = c;
    Invalidate();
}

bool QTabContainer::OnSetFocus( HWND hwnd )
{
    int len = m_tabList.GetSize();

    if ( !len )
        return false;

    QTab & ctn =  m_tabList[m_currentTab];
    ctn.pChild->SetFocus();
    return true;
}


bool QTabContainer::Find( QPanel * p )
{
    int len = m_tabList.GetSize();

    for ( int iCont = 0; iCont < len ; iCont++ )
    {
        QTab & ct =   m_tabList[iCont];

        if ( p ==  ct.pChild )
            return true;
    }

    return false;
}


bool QTabContainer::OnPreCreate( CREATESTRUCT & cs )
{
    QControl::OnPreCreate( cs );

    cs.style =   WS_VISIBLE | WS_CHILD | WS_CLIPCHILDREN;
    return true;
}


bool QTabContainer::Create( QWindow * parent, int id, UINT style )
{
    m_style = style;
    bool bo = QControl::Create( parent, id, style );



    QLogFont log;
    log.SetMenuFont();
    m_font.Attach( log.CreateFontIndirect() );

    pen.CreatePen( PS_SOLID, 1,  ::GetSysColor( COLOR_BTNSHADOW )   );
    m_theme.OpenThemeData( GetHandle(), QTAB );


    return bo;

}
void  QTabContainer::RemoveTab( QPanel  * p )
{
    int len = m_tabList.GetSize();

    for ( int iCont = 0; iCont < len ; iCont++ )
    {
        QTab & ct =   m_tabList[iCont];

        if ( p ==  ct.pChild )
        {
            RemoveTab( iCont );
            return ;
        }

    }
}
int	QTabContainer::GetTabCount()
{
    return m_tabList.GetSize();

}
void  QTabContainer::RemoveTab( int nrTab )
{

    if ( m_tabList.GetSize() <= 1 )
        return;

    QTab  & ct =   m_tabList[nrTab];
    QPanel * tempWin = ct.pChild;

    bool bo = tempWin->ClosePanel();

    if ( false == bo )
        return;


    m_tabList.Remove( nrTab, 1 );


    if ( m_currentTab > 0 )
        if ( m_currentTab >= nrTab )
            m_currentTab = m_currentTab - 1;


    QTab & ctn =  m_tabList[m_currentTab];
    ctn.pChild->Show();
    ctn.pChild->SetFocus();



    delete tempWin;


    RecalcLayout();//neceasr pt a aseza clientul
    Invalidate();
    //Update();
}


//insert after curent
bool  QTabContainer::InsertTab( QPanel * pChild, QString str, UINT id )
{
    ASSERT( pChild );
    bool bo = pChild->Create( this, id );

    if ( !bo )
        return false;

    QTab   tab( pChild, str );



    if ( m_tabList.IsEmpty() )
    {
        m_tabList.Add( tab );
        pChild->Show();
        pChild->SetFocus();
        m_currentTab = 0;

    }
    else
    {
        m_tabList.Insert( tab, m_currentTab + 1 );


        QTab & ctn =  m_tabList[m_currentTab];
        ctn.pChild->Hide();
        m_currentTab++;

        pChild->Show();
        pChild->SetFocus();



    }



    RecalcLayout();//neceasr pt a aseza clientul
    Invalidate();
    return true;



}

bool  QTabContainer::AddTab( QPanel * pChild, QString str, UINT id )
{
    ASSERT( pChild );
    bool bo = pChild->Create( this, id );

    if ( !bo )
        return false;


    QTab   tab( pChild, str );

    bool empty = m_tabList.IsEmpty();

    m_tabList.Add(  tab );

    if ( empty )
    {

        pChild->Show();
        pChild->SetFocus();
        m_currentTab = 0;
    }
    else
    {
        pChild->Show();
        pChild->SetFocus();


        QTab & ctn =  m_tabList[m_currentTab];
        ctn.pChild->Hide();

    }

    //signal
    OnTabChange();
    m_currentTab = m_tabList.GetSize() - 1;

    RecalcLayout();//neceasr pt a aseza clientul
    Invalidate();
    return true;
}



int  QTabContainer::GetCurrentTab()
{
    return m_currentTab;

}

QWindow  * QTabContainer::GetCurrentWindow()
{
    return  GetChildWindow( m_currentTab );
}

QWindow  * QTabContainer::GetChildWindow( int tab )
{
    if ( m_tabList.GetSize() == 0 )
        return nullptr;


    ASSERT( m_tabList.GetSize() > 0 );
    QTab & ctn  =  m_tabList[tab];
    return  ctn.pChild;
}

bool QTabContainer::OnSize( int type, int cx, int cy )
{
    if ( m_tabList.GetSize() )
    {
        RecalcLayout();
        Invalidate();
    }

    return true;
}

void  QTabContainer::RecalcLayout()
{
    if ( ! m_tabList.GetSize( ) )
        return;


    QRect r = GetClientRect();

    if ( r.IsRectEmpty() )
        return;



    int xx = SPACE_LINE;
    int yy = SPACE_LINE;
    int ww = ( r.Width() - 2 * SPACE_LINE ) /  m_tabList.GetSize();
    int hh = SPACE_TAB;

    ////for maxSize tabs
    if ( m_style == TS_MAXTAB )
    {
        if ( ww  > MAX_TAB_SIZE )
            ww = MAX_TAB_SIZE;
    }




    r.top = SPACE_TAB;
    r.left ++;
    r.right --;
    r.bottom --;

    for ( int iCont = 0; iCont < m_tabList.GetSize(); iCont++ )
    {
        QTab & ct  =  m_tabList[iCont];
        QWindow * m_tempWin = ct.pChild;

        if ( iCont == m_currentTab )
            ct.rect  = QRect( xx - SPACE_ACTIVE, yy - SPACE_ACTIVE, xx + ww + SPACE_ACTIVE, hh  );
        else
            ct.rect  = QRect( xx, yy, xx + ww, hh  );

        xx += ww;




        m_tempWin->SetWindowPos( nullptr,
                                 r.left,
                                 r.top,
                                 r.Width(),
                                 r.Height(),
                                 SWP_NOACTIVATE
                                 | SWP_NOZORDER
                                 //|SWP_NOCOPYBITS
                                 //|SWP_FRAMECHANGED
                                 //|SWP_NOSENDCHANGING
                                 //|SWP_NOREDRAW
                               );


    }

}

bool QTabContainer::OnLButtonDblClk( UINT flags, QPoint & point )
{
    return true;
}

bool QTabContainer::OnLButtonDown( UINT flags, QPoint & point )
{
    if ( ! m_tabList.GetSize() )
        return true;

    QTab   &  ct  =   m_tabList[m_currentTab];

    if (  ct.rect.PtInRect( point ) )
    {
        ct.pChild->SetFocus();
        return true;
    }


    for ( int iCont = 0; iCont < m_tabList.GetSize(); iCont++ )
    {
        QTab & ct1 =   m_tabList[iCont];
        QWindow * win = ct1.pChild;

        if (  ct1.rect.PtInRect( point ) )
        {
            QTab & ct2 =   m_tabList[m_currentTab];
            QWindow * win2 = ct2.pChild;


            win->Show();
            win2->Hide();
            win->SetFocus();
            m_currentTab = iCont;

            RecalcLayout();//neceasr pt a reface dreptunghiul focusat
            Invalidate();//pregateste
            //Update();//deseneaza

            return true;
        }
    }

    return true;
}
void QTabContainer::DrawTabs( QGraphics * pdc, int iSel )
{
    if ( ! m_tabList.GetSize() )
        return;

    QRect rcClient	= GetClientRect();
    QRect rcb		= rcClient; //border
    QMemoryGraphics dc( pdc, rcClient );

    //dupa
    rcClient.bottom = SPACE_TAB;



    QSelector sel_2( &dc, pen );
    QSelector sel_3( &dc, m_font );



    dc.SetBkMode( TRANSPARENT );
    dc.FillSolidRect( rcClient, m_bkColor );
    //m_theme.DrawThemeBackground( dc, TABP_PANE, 0, rcClient, nullptr);



    QBrush brush( ::GetSysColor( COLOR_BTNFACE )  );


    for ( int iCont = 0; iCont < m_tabList.GetSize(); iCont++ )
    {
        QTab & ct =   m_tabList[iCont];
        QRect rc = ct.rect;

        if ( iCont == m_currentTab  )
        {
            if ( m_theme )
                m_theme.DrawThemeBackground( dc, TABP_TOPTABITEM, TIBES_SELECTED, rc, nullptr );
            else
            {
                dc.Rectangle( rc );
                //dc.FillSolidRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT));
            }
        }
        else if ( iCont == iSel )
        {
            if ( m_theme )
                m_theme.DrawThemeBackground( dc, TABP_TABITEM, TIBES_HOT, rc, nullptr );
            else
            {
                dc.Rectangle( rc );
                //dc.FillSolidRect(rc, ::GetSysColor(COLOR_BTNHIGHLIGHT));
            }
        }
        else
        {
            if ( m_theme )
                m_theme.DrawThemeBackground( dc, TABP_TABITEM, TIS_NORMAL, rc, nullptr );
            else
            {

                QSelector sel_4( &dc, brush );
                dc.Rectangle( rc );
            }
        }

        QRect rt = ct.rect;
        rt.DeflateRect( 2, 0 );

        dc.DrawText( ct.title, rt, DT_END_ELLIPSIS | DT_VCENTER | DT_CENTER | DT_SINGLELINE );

    }



    QRect rr = rcClient;
    rr.top = SPACE_TAB - SPACE_LINE;
    rr.bottom = SPACE_TAB;

    //theme.DrawThemeBackground( dc, TABP_PANE, 0, rr, nullptr);

    dc.FillSolidRect( rr, ::GetSysColor( COLOR_BTNHIGHLIGHT ) );



    QTab & ct =   m_tabList[m_currentTab];

    dc.MoveTo( 0, SPACE_TAB - SPACE_LINE );
    dc.LineTo( ct.rect.left + 1, SPACE_TAB - SPACE_LINE );

    dc.MoveTo( ct.rect.right - 1, SPACE_TAB - SPACE_LINE );
    dc.LineTo( rcb.right - 1, SPACE_TAB - SPACE_LINE );

    dc.LineTo( rcb.right - 1, rcb.bottom - 1 );
    dc.LineTo( rcb.left, rcb.bottom - 1 );
    dc.LineTo( rcb.left, SPACE_TAB - SPACE_LINE );


}



bool QTabContainer::OnMouseLeave()
{
    Invalidate();
    /// stop tracking
    //Track(this);
    StopTrackEvents();

    return true;
}

bool QTabContainer::OnMouseMove( UINT flags, QPoint & point )
{
    if ( ! IsTracking() )
    {
        TrackMouseEvents( this, TME_LEAVE );
    }

    int iSel = -1;

    for ( int iCont = 0; iCont < m_tabList.GetSize(); iCont++ )
    {
        QTab & ct =   m_tabList[iCont];

        if (  ct.rect.PtInRect( point ) )
        {
            iSel =  iCont;
        }
    }

    //else e in zona dar pe niciun tab
    QClientGraphics dc( this );
    DrawTabs( &dc, iSel );
    return true;
}


bool  QTabContainer::OnEraseBackground( QGraphics * pdc )
{
    if ( m_tabList.GetSize() )
        return true;


    //picteaza ceva fundal
    return false;
}
bool  QTabContainer::OnPaint( QGraphics * pdc )
{
    DrawTabs( pdc );
    return true;
}


void QTabContainer::MoveNextTab( bool next )
{
    int nrtabs = m_tabList.GetSize();

    if ( nrtabs  <= 1 )
        return ;


    int inext = 0;

    if  ( next )
        inext =   ( m_currentTab + 1 ) % nrtabs;
    else
    {
        inext = m_currentTab - 1;

        if ( inext < 0 )
            inext = nrtabs - 1;
    }

    SetActiveTab( inext );

}

void  QTabContainer::SetActiveTabByID( int unicid )
{
    int nrtabs = m_tabList.GetSize();

    for ( int iCont = 0; iCont < nrtabs  ; iCont++ )
    {
        QTab & ct =   m_tabList[iCont];

        if ( ct.id == unicid &&  iCont != m_currentTab )
        {
            QWindow * win2 = ct.pChild;
            QTab & ct2 =   m_tabList[m_currentTab];
            QWindow * win1 = ct2.pChild;
            win2->Show();
            win1->Hide();
            win2->SetFocus();


            m_currentTab = iCont;
            RecalcLayout();
            OnTabChange();
            break;
        }
    }
}

void QTabContainer::SetActiveTab( int tab )
{

    if ( tab == m_currentTab )
        return;

    ASSERT( tab >= 0 );
    ASSERT ( tab <  m_tabList.GetSize() );



    QTab & ct2 =   m_tabList[m_currentTab];
    QWindow * win2 = ct2.pChild;

    QTab & ct1 =   m_tabList[tab];
    QWindow * win = ct1.pChild;


    win->Show();
    win2->Hide();
    win->SetFocus();
    m_currentTab = tab;

    OnTabChange();
    Invalidate();//pregateste
    //Update();//deseneaza



}